home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / Edit.pak / EDITX.CPP < prev    next >
C/C++ Source or Header  |  1996-01-08  |  15KB  |  515 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //----------------------------------------------------------------------------
  5. #include <owl/pch.h>
  6. #include <owl/applicat.h>
  7. #include <owl/framewin.h>
  8. #include <owl/static.h>
  9. #include <owl/edit.h>
  10. #include <owl/inputdia.h>
  11. #include <owl/opensave.h>
  12. #include <owl/validate.h>
  13. #include <fstream.h>
  14. #include <cstring.h>
  15.  
  16. #include "edit.rh"
  17.  
  18. // Control ids:
  19. //
  20. const int ID_EXAMPLE_EDIT       = 200;
  21.  
  22. // Message ids:
  23. //
  24. const int CN_UPDATE             = 300;
  25.  
  26. class TExampleEdit : public TEdit {
  27.   public:
  28.     TExampleEdit(TWindow*        parent,
  29.                  int             id,
  30.                  const char far* text,
  31.                  int x, int y, int w, int h,
  32.                  uint            textLen = EditTextLen + 1,
  33.                  bool            multiline = true,
  34.                  TModule*        module = 0 )
  35.     :
  36.       TEdit(parent, id, text, x, y, w, h, textLen, multiline, module)
  37.     {
  38.       LastCBOpStr = " ";
  39.     }
  40.  
  41.     // override to setup 'FileData' structure.
  42.     //
  43.     void SetupWindow();
  44.  
  45.     // override to update text fields.
  46.     //
  47.     void    CmEditCut();                   // CM_EDITCUT
  48.     void    CmEditCopy();                  // CM_EDITCOPY
  49.     void    CmEditPaste();                 // CM_EDITPASTE
  50.     void    CmEditDelete();                // CM_EDITDELETE
  51.     void    CmEditClear();                 // CM_EDITCLEAR
  52.     void    CmEditUndo();                  // CM_EDITUNDO
  53.     void    EvKeyDown(uint key, uint repeatCount, uint flags);
  54.     void    EvLButtonDown(uint modKeys, TPoint& point);
  55.  
  56.     // Newly defined functions (not defined by base classes):
  57.     //
  58.     void NotifyParent(int notification);
  59.     void SaveText();
  60.     void RestoreText();
  61.     const string& GetLastCBOpStr() const {return LastCBOpStr;}
  62.  
  63.     string                  LastCBOpStr;   // string value of last CB operation.
  64.     static const unsigned   EditTextLen;   // length of edit control text.
  65.  
  66.   private:
  67.     TOpenSaveDialog::TData  FileData;      // save/restore info.
  68.  
  69.   DECLARE_RESPONSE_TABLE(TExampleEdit);
  70. };
  71.  
  72. DEFINE_RESPONSE_TABLE1(TExampleEdit, TEdit)
  73.   EV_COMMAND(CM_EDITCUT,     CmEditCut),
  74.   EV_COMMAND(CM_EDITCOPY,    CmEditCopy),
  75.   EV_COMMAND(CM_EDITPASTE,   CmEditPaste),
  76.   EV_COMMAND(CM_EDITDELETE,  CmEditDelete),
  77.   EV_COMMAND(CM_EDITCLEAR,   CmEditClear),
  78.   EV_COMMAND(CM_EDITUNDO,    CmEditUndo),
  79.   EV_WM_KEYDOWN,
  80.   EV_WM_LBUTTONDOWN,
  81. END_RESPONSE_TABLE;
  82.  
  83. const unsigned TExampleEdit::EditTextLen   = 1000;
  84.  
  85. void
  86. TExampleEdit::SetupWindow()
  87. {
  88.   TEdit::SetupWindow();
  89.   FileData.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  90.   FileData.SetFilter("Text files (*.TXT)|*.TXT|AllFiles (*.*)|*.*|");
  91. }
  92.  
  93. //
  94. // The next function group simply notifies the app to update the text fields
  95. // then calls the base class version to do the actual processing.
  96. //
  97.  
  98. void
  99. TExampleEdit::CmEditCut()
  100. {
  101.   LastCBOpStr = "Cut";
  102.   NotifyParent(CN_UPDATE);
  103.   TEdit::CmEditCut();
  104.   NotifyParent(CN_UPDATE);
  105.   TEdit::CmEditCut();
  106. }
  107.  
  108. void
  109. TExampleEdit::CmEditCopy()
  110. {
  111.   LastCBOpStr = "Copy";
  112.   NotifyParent(CN_UPDATE);
  113.   TEdit::CmEditCopy();
  114. }
  115.  
  116. void
  117. TExampleEdit::CmEditPaste()
  118. {
  119.   LastCBOpStr = "Paste";
  120.   NotifyParent(CN_UPDATE);
  121.   TEdit::CmEditPaste();
  122.   NotifyParent(CN_UPDATE);
  123. }
  124.  
  125. void
  126. TExampleEdit::CmEditDelete()
  127. {
  128.   LastCBOpStr = "Delete";
  129.   NotifyParent(CN_UPDATE);
  130.   TEdit::CmEditDelete();
  131.   NotifyParent(CN_UPDATE);
  132. }
  133.  
  134. void
  135. TExampleEdit::CmEditClear()
  136. {
  137.   TEdit::CmEditClear();
  138.   LastCBOpStr = "Clear";
  139.   NotifyParent(CN_UPDATE);
  140. }
  141.  
  142. void
  143. TExampleEdit::CmEditUndo()
  144. {
  145.   TEdit::CmEditUndo();
  146.   LastCBOpStr = "Undo";
  147.   NotifyParent(CN_UPDATE);
  148. }
  149.  
  150. void
  151. TExampleEdit::EvKeyDown(uint key, uint repeatCount, uint flags)
  152. {
  153.   TEdit::EvKeyDown(key, repeatCount, flags);
  154.   NotifyParent(CN_UPDATE);
  155. }
  156.  
  157. void
  158. TExampleEdit::EvLButtonDown(uint modKeys, TPoint& point)
  159. {
  160.   TEdit::EvLButtonDown(modKeys, point);
  161.   NotifyParent(CN_UPDATE);
  162. }
  163.  
  164. //
  165. // NotifyParent(). 'easy' method of notifing the parent of an event.
  166. // Notifies immediately
  167. void
  168. TExampleEdit::NotifyParent(int notification)
  169. {
  170.   Parent->SendNotification(Attr.Id, notification, HWindow);
  171. }
  172.  
  173. //
  174. // SaveText().  Save text portion of edit control to a file.
  175. //
  176. void
  177. TExampleEdit::SaveText()
  178. {
  179.   if (TFileSaveDialog(GetApplication()->MainWindow, FileData).Execute() == IDOK) {
  180.     ofstream    ofs(FileData.FileName, ios::out|ios::binary);
  181.     unsigned    maxLen = EditTextLen;
  182.     char far*   buffer = LockBuffer();
  183.     unsigned    size = min(maxLen, strlen(buffer));
  184.  
  185.     for (unsigned i = 0; i < size && buffer[i]; i++)
  186.       ofs.put(buffer[i]);
  187.     UnlockBuffer(buffer);
  188.   }
  189. }
  190.  
  191. //
  192. // RestoreText().  Restore or read in text from a file.  Uses the first
  193. // 'EditTextLen' characters from file.
  194. //
  195. void
  196. TExampleEdit::RestoreText()
  197. {
  198.   if (TFileOpenDialog(GetApplication()->MainWindow, FileData).Execute() == IDOK) {
  199.     Clear();
  200.  
  201.     ifstream    ifs(FileData.FileName);
  202.     char far*   buffer = LockBuffer(EditTextLen + 1);
  203.  
  204.     unsigned i;
  205.     for (i = 0; i < EditTextLen && !ifs.eof(); i++) {
  206.       buffer[i] = (char)ifs.get();
  207.       if (buffer[i] == '\n' && ifs.peek() != '\r') {
  208.         buffer[i] = '\r';
  209.         buffer[++i] = '\n';
  210.       }
  211.     }
  212.     if (i)
  213.       buffer[i-1] = 0;
  214.     UnlockBuffer(buffer, TRUE);
  215.     NotifyParent(CN_UPDATE);
  216.   }
  217. }
  218.  
  219. //
  220. // class TEditWindow
  221. // ~~~~~ ~~~~~~~~~~~
  222. class TEditWindow : public TWindow {
  223.   public:
  224.     TEditWindow();
  225.  
  226.     void SetupWindow();
  227.  
  228.     // message response functions
  229.     //
  230.     void CmUpdate() {UpdateTextFields();} // Edit control notification.
  231.     void CmInsertText();                  // insert text at char pos.
  232.     void CmDeleteSubText();               // delete subtext.
  233.     void CmDeleteLine();                  // delete line of text.
  234.     void CmSaveText();                    // save text in edit cntl.
  235.     void CmRestoreText();                 // restore from file into edit cntl.
  236.  
  237.   private:
  238.     TExampleEdit* EditCntl;               // edit control
  239.     TStatic*      NbrLinesText;           // text of number of lines.
  240.     TStatic*      CurLineNbrText;         // current line number.
  241.     TStatic*      CurLineText;            // current line, 1st N chars.
  242.     TStatic*      CurLineLenText;         // length of current line.
  243.     TStatic*      FirstVisibleLineText;   // line # of 1st visible line.
  244.     TStatic*      IsModifiedText;         // has edit control been modified.
  245.     TStatic*      LastCBOpText;           // last clipboard operation.
  246.     TStatic*      CurSelText;             // first N chars of selected text.
  247.  
  248.     static const unsigned InputTextLen;   // length of input text.
  249.     static const unsigned FirstNChars;    // first n characters to display.
  250.  
  251.     void  ResetTextFields();              // reset text fields to init values.
  252.     void  UpdateTextFields();             // updates from edit control
  253.  
  254.     int InputString(char* prompt, char* s);     // read string from user.
  255.     int InputNumber(char* prompt, unsigned& n); // read number from user
  256.  
  257.   DECLARE_RESPONSE_TABLE(TEditWindow);
  258. };
  259.  
  260. DEFINE_RESPONSE_TABLE1(TEditWindow, TWindow)
  261.   EV_CHILD_NOTIFY(ID_EXAMPLE_EDIT, CN_UPDATE, CmUpdate),
  262.   EV_EN_VSCROLL(ID_EXAMPLE_EDIT,     CmUpdate),
  263.   EV_COMMAND(CM_INSERT_TEXT,         CmInsertText),
  264.   EV_COMMAND(CM_DELETE_SUBTEXT,      CmDeleteSubText),
  265.   EV_COMMAND(CM_DELETE_LINE,         CmDeleteLine),
  266.   EV_COMMAND(CM_SAVE_TEXT,           CmSaveText),
  267.   EV_COMMAND(CM_RESTORE_TEXT,        CmRestoreText),
  268. END_RESPONSE_TABLE;
  269.  
  270. const unsigned TEditWindow::InputTextLen  = 51;
  271. const unsigned TEditWindow::FirstNChars   = 20;
  272.  
  273. //
  274. // Constructor.  Setup menu and text areas.
  275. //
  276. TEditWindow::TEditWindow()
  277. :
  278.   TWindow(0, 0, 0)
  279. {
  280.   const int labelStartX = 10,
  281.             textStartY = 225,
  282.             textHeight = 16,
  283.             textStartX = labelStartX + 250;
  284.  
  285.  
  286.   // Create Edit control.
  287.   //
  288.   EditCntl = new TExampleEdit(this, ID_EXAMPLE_EDIT, "", 10, 10, 500, 200);
  289.  
  290.   // setup static text areas.
  291.   //
  292.   new TStatic(this, -1, "Number of lines:",  labelStartX, textStartY,
  293.               160, textHeight, 16);
  294.   NbrLinesText = new TStatic(this, -1, "0",  textStartX, textStartY,
  295.               50, textHeight, 5);
  296.   new TStatic(this, -1, "current line number:",  labelStartX,
  297.               textStartY + textHeight, 200, textHeight, 20);
  298.   CurLineNbrText = new TStatic(this, -1, "0",  textStartX,
  299.               textStartY + textHeight, 50, textHeight, 5);
  300.   new TStatic(this, -1, "1st 20 chars of current line:",  labelStartX,
  301.               textStartY + textHeight * 2, 290, textHeight, 29);
  302.   CurLineText = new TStatic(this, -1, "",  textStartX,
  303.               textStartY + textHeight * 2, FirstNChars * 10, textHeight,
  304.               FirstNChars);
  305.   new TStatic(this, -1, "length of current line:",  labelStartX,
  306.               textStartY + textHeight * 3, 230, textHeight, 23);
  307.   CurLineLenText = new TStatic(this, -1, "0",  textStartX,
  308.               textStartY + textHeight * 3, 50, textHeight, 5);
  309.   new TStatic(this, -1, "line number of 1st visible list:",  labelStartX,
  310.               textStartY + textHeight * 4, 320, textHeight, 32);
  311.   FirstVisibleLineText = new TStatic(this, -1, "0",  textStartX,
  312.               textStartY + textHeight * 4, 50, textHeight, 5);
  313.   new TStatic(this, -1, "has edit control been modified:",  labelStartX,
  314.               textStartY + textHeight * 5, 310, textHeight, 31);
  315.   IsModifiedText = new TStatic(this, -1, "No",  textStartX,
  316.               textStartY + textHeight * 5, 50, textHeight, 5);
  317.   new TStatic(this, -1, "last clipboard operation:",  labelStartX,
  318.               textStartY + textHeight * 6, 250, textHeight, 25);
  319.   LastCBOpText = new TStatic(this, -1, "",  textStartX,
  320.               textStartY + textHeight * 6, 100, textHeight, 10);
  321.   new TStatic(this, -1, "1st 20 chars of last selected text:",  labelStartX,
  322.               textStartY + textHeight * 7, 350, textHeight, 35);
  323.   CurSelText= new TStatic(this, -1, "",  textStartX,
  324.               textStartY + textHeight * 7, FirstNChars * 10, textHeight,
  325.               FirstNChars);
  326. }
  327.  
  328. void
  329. TEditWindow::SetupWindow()
  330. {
  331.   TWindow::SetupWindow();
  332.   UpdateTextFields();
  333. }
  334.  
  335. //
  336. // CmInsertText(). Insert text at character position input be user. If pos
  337. // is beyond end of edit buffer then the insert takes place at the end of
  338. // buffer (append).
  339. //
  340. void
  341. TEditWindow::CmInsertText()
  342. {
  343.   char     buf[InputTextLen] = "";
  344.   unsigned pos;
  345.  
  346.   if (!InputNumber("Enter position:", pos))
  347.     return;
  348.   EditCntl->SetSelection(pos, pos);
  349.  
  350.   buf[0] = 0;
  351.   if (!InputString("Enter string:", buf))
  352.     return;
  353.   EditCntl->Insert(buf);
  354.   UpdateTextFields();
  355. }
  356.  
  357. //
  358. // CmDeleteSubText().  Delete characters between start position and end
  359. // position (input by user).
  360. //
  361. void
  362. TEditWindow::CmDeleteSubText()
  363. {
  364.   unsigned sPos, ePos;
  365.  
  366.   if (!InputNumber("Enter starting position", sPos))
  367.     return;
  368.  
  369.   if (!InputNumber("Enter ending position", ePos))
  370.     return;
  371.  
  372.   EditCntl->DeleteSubText(sPos, ePos);
  373.   UpdateTextFields();
  374. }
  375.  
  376. //
  377. // CmDeleteLine().  Delete line of text.  Line number input by user.
  378. //
  379. void
  380. TEditWindow::CmDeleteLine()
  381. {
  382.   unsigned line;
  383.  
  384.   if (!InputNumber("Enter line number:", line))
  385.     return;
  386.   EditCntl->DeleteLine(line);
  387.   UpdateTextFields();
  388. }
  389.  
  390. //
  391. // SaveText().  Save text of edit control to a file.
  392. //
  393. void TEditWindow::CmSaveText()
  394. {
  395.   EditCntl->SaveText();
  396. }
  397.  
  398. //
  399. // RestoreText().  retore text of edit control from a file.
  400. //
  401. void TEditWindow::CmRestoreText()
  402. {
  403.   EditCntl->RestoreText();
  404.   UpdateTextFields();
  405. }
  406.  
  407. //
  408. // UpdateTextFields(). Updates text fields that reflex the edit control's state.
  409. //
  410. void
  411. TEditWindow::UpdateTextFields()
  412. {
  413.   char buf[FirstNChars+1] = "";
  414.   uint sPos, ePos, curLine;
  415.  
  416.   // make sure all pending messages are processed first
  417.   //
  418.   GetApplication()->PumpWaitingMessages();
  419.  
  420.   // get the line that the caret is currently on.
  421.   //
  422.   EditCntl->GetSelection(sPos, ePos);
  423.   curLine = EditCntl->GetLineFromPos(ePos);
  424.  
  425.   itoa(curLine, buf, 10);
  426.   CurLineNbrText->SetText(buf);
  427.  
  428.   itoa(EditCntl->GetNumLines(), buf, 10);
  429.   NbrLinesText->SetText(buf);
  430.  
  431.   EditCntl->GetLine(buf, FirstNChars, curLine);
  432.   CurLineText->SetText(buf);
  433.  
  434.   itoa(EditCntl->GetLineLength(curLine), buf, 10);
  435.   CurLineLenText->SetText(buf);
  436.  
  437.   itoa(EditCntl->GetFirstVisibleLine(), buf, 10);
  438.   FirstVisibleLineText->SetText(buf);
  439.  
  440.   if (EditCntl->IsModified())
  441.     IsModifiedText->SetText("Yes");
  442.   else
  443.     IsModifiedText->SetText("No");
  444.  
  445.   LastCBOpText->SetText(EditCntl->LastCBOpStr.c_str());
  446.  
  447.   EditCntl->GetSubText(buf, sPos, min(ePos, sPos+(unsigned)FirstNChars));
  448.   if (buf[0])
  449.     CurSelText->SetText(buf);
  450. }
  451.  
  452. //
  453. // ResetTextFields(). Reset text fields to blanks.
  454. //
  455. void
  456. TEditWindow::ResetTextFields()
  457. {
  458.   NbrLinesText->SetText("0");
  459.   CurLineNbrText->SetText("0");
  460.   CurLineText->SetText("");
  461.   CurLineLenText->SetText("0");
  462.   FirstVisibleLineText->SetText("0");
  463.   IsModifiedText->SetText("No");
  464.   LastCBOpText->SetText("");
  465.   CurSelText->SetText("");
  466. }
  467.  
  468. //
  469. // InputString(). Get string from user.  Return 1 if successful, 0 otherwise.
  470. // assumes buffer size of InputTextLen.
  471. //
  472. int
  473. TEditWindow::InputString(char* prompt, char* s)
  474. {
  475.   return TInputDialog(this, "String", prompt, s, InputTextLen).Execute() == IDOK;
  476. }
  477.  
  478. //
  479. // InputNumber(). Get number from user.  Return 1 if successful, 0 otherwise.
  480. //
  481. int
  482. TEditWindow::InputNumber(char* prompt, unsigned& n)
  483. {
  484.   char buf[10] = "";
  485.   int  ok = TInputDialog(this, "Number", prompt, buf, sizeof(buf), 0,
  486.                          new TFilterValidator("0-9")).Execute() == IDOK;
  487.   if (ok)
  488.     n = atoi(buf);
  489.   return ok;
  490. }
  491.  
  492. //----------------------------------------------------------------------------
  493.  
  494. class TExampleEditApp : public TApplication {
  495.   public:
  496.     void InitMainWindow();
  497. };
  498.  
  499. void
  500. TExampleEditApp::InitMainWindow()
  501. {
  502.   TFrameWindow* frame = new TFrameWindow(0, "Edit Control Example",
  503.     new TEditWindow);
  504.   // setup menu
  505.   //
  506.   frame->AssignMenu(IDM_EXAMPLE_EDIT);
  507.   SetMainWindow(frame);
  508. }
  509.  
  510. int
  511. OwlMain(int /*argc*/, char* /*argv*/ [])
  512. {
  513.   return TExampleEditApp().Run();
  514. }
  515.